`timescale 1ns / 1ps

module ExceptionUnit (
    input wire clk,
    input wire rst,
    input wire csr_rw_in,
    // write/set/clear (funct bits from instruction)
    input wire [1:0] csr_wsc_mode_in,
    input wire csr_w_imm_mux,
    input wire [11:0] csr_rw_addr_in,
    input wire [31:0] csr_w_data_reg,
    input wire [4:0] csr_w_data_imm,
    output wire [31:0] csr_r_data_out,

    input wire interrupt,
    input wire illegal_inst,
    input wire l_access_fault,
    input wire s_access_fault,
    input wire ecall_m,

    input wire mret,

    input wire [31:0] epc_cur,
    input wire [31:0] epc_next,
    output wire [31:0] PC_redirect,
    output wire redirect_mux,

    output wire reg_FD_flush,
    output wire reg_DE_flush,
    output wire reg_EM_flush,
    output wire reg_MW_flush,
    output wire RegWrite_cancel,
    output wire MemWrite_cancel
);
  // According to the diagram, design the Exception Unit
  // You can modify any code in this file if needed!

  // mcause exception code
  parameter [31:0] MCAUSE_ILLEGAL_INST = 32'd2;
  parameter [31:0] MCAUSE_L_ACCESS_FAULT = 32'd5;
  parameter [31:0] MCAUSE_S_ACCESS_FAULT = 32'd7;
  parameter [31:0] MCAUSE_ECALL_M = 32'd11;

  // mcause interruption code
  parameter [31:0] MCAUSE_SOFT_INT = 32'd3;
  parameter [31:0] MCAUSE_MACHINE_EXT_INT = 32'd11;

  // CSR register addresses - mapped
  parameter [11:0] CSR_MSTATUS = 12'h300;
  parameter [11:0] CSR_MTVEC = 12'h305;
  parameter [11:0] CSR_MEPC = 12'h341;
  parameter [11:0] CSR_MCAUSE = 12'h342;
  parameter [11:0] CSR_MTVAL = 12'h343;

  reg [11:0] csr_waddr;
  reg [31:0] csr_wdata;
  reg csr_w;
  reg [1:0] csr_wsc;
  wire [11:0] csr_raddr;

  wire [31:0] mstatus;
  wire [31:0] csr_rdata;

  CSRRegs csr (
      .clk(clk),
      .rst(rst),
      .csr_w(csr_w),
      .raddr(csr_raddr),
      .waddr(csr_waddr),
      .wdata(csr_wdata),
      .rdata(csr_rdata),
      .mstatus(mstatus),
      .csr_wsc_mode(csr_wsc)
  );
endmodule
